
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "map.h"

void mapInit(map_head_t *map_head){
    map_head->rb_node = NULL;
}

int mapAdd(map_head_t *map_head,MyMapNode *insert_node){
    struct rb_node **new_node = &(map_head->rb_node);
    struct rb_node *parent = NULL;
    MyMapNode *this_node = NULL;
    int result = 0;
    while(*new_node){
        this_node = rb_entry_safe(*new_node,MyMapNode,node);
        parent = *new_node;
        result = memcmp(this_node,insert_node,sizeof(MyMapNode));
        if(0 < result) {
            new_node = &(this_node->node.rb_right);
        } else if(0 > result) {
            new_node = &(this_node->node.rb_left);
        } else {
            //重复了
            return 1;
        }
    }
    MyMapNode *new = (MyMapNode *)calloc(1,sizeof(MyMapNode));
    if(NULL == new){
        printf("create insert node failed\n");
        return -1;
    }
    memcpy(new,insert_node,sizeof(MyMapNode));
    rb_link_node(&new->node,parent,new_node);
    rb_insert_color(&new->node,map_head);
    return 0;
}

MyMapNode *mapFind(map_head_t *map_head,int key){
    struct rb_node **new_node = &(map_head->rb_node);
    MyMapNode *this_node = NULL;
    int result = 0;
    while(*new_node){
        this_node = rb_entry_safe(*new_node,MyMapNode,node);
        result = memcmp(&this_node->key,&key,sizeof(int));
        if(0 < result){
            new_node = &((*new_node)->rb_right);
        }else if(0 > result){
            new_node = &((*new_node)->rb_left);
        }else{
            printf("find success\n");
            return this_node;
        }
    }
    printf("Don't find \n");
    return NULL;
}

int mapDelete(map_head_t *map_head,int key){
    MyMapNode *del_node = mapFind(map_head,key);
    if(NULL == del_node){
        printf("no this node\n");
        return -1;
    }
    rb_erase(&del_node->node,map_head);
    free(del_node);
    del_node = NULL;
    return 0;
}

int mapChange(map_head_t *map_head,int key,uint32_t new_value){
    MyMapNode *del_node = mapFind(map_head,key);
    if(NULL == del_node){
        printf("no this node\n");
        return -1;
    }
    //TODO
    return 0;
}

int mapDestory(map_head_t *map_head){
    struct rb_node *next = rb_first(map_head);
    MyMapNode *this_node = NULL;
    while(next){
        this_node = rb_entry_safe(next,MyMapNode,node);
        next = rb_next(&this_node->node);
        rb_erase(&this_node->node,map_head);
        free(this_node);
        this_node = NULL;
    }
    return 0;
}

void mapShow(map_head_t *map_head){
    MyMapNode *pos,*n;
    rbtree_postorder_for_each_entry_safe(pos,n,map_head,node){
        printf("key:%d val:%u\n",pos->key,pos->value);
    }
}
